package com.example.myapplication1;


import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.graphics.YuvImage;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;

import android.speech.tts.TextToSpeech;
import android.util.DisplayMetrics;
import android.util.JsonReader;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;


import com.example.myapplication1.entity.ChooseBabyDto;
import com.example.myapplication1.entity.Message;
import com.example.myapplication1.util.OkHttpClientUtils;
import com.google.gson.Gson;

import org.json.JSONObject;
import org.json.JSONStringer;

import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

public class IndexActivity extends AppCompatActivity {

    // 声明变量
    private TextureView textureView;  // 用于预览相机画面的TextureView
    private CameraDevice cameraDevice;  // 相机设备
    private CameraCaptureSession cameraCaptureSession;  // 相机捕获会话
    private CaptureRequest.Builder captureRequestBuilder;  // 用于构建捕获请求
    private Size imageDimension;  // 图像尺寸
    private ImageReader imageReader;  // 用于读取图像数据

    private WebSocket webSocket;  // WebSocket对象，用于与服务器进行通信

    private String currentBaby="宝宝1";
    private int currentBabyId=3;

    private int sleepCount=0;

    private int awakeCount=0;

    private int kickCount=0;
    String status="";

    //获取当前选中宝宝
    public ChooseBabyDto getCurrentBaby() {
        try {
            OkHttpClientUtils httpClient = new OkHttpClientUtils();
            String url = "http://admin.mi9688.top/api1/user/get-baby-choose-name-collect";
            String response = httpClient.get(url);
            Gson gson = new Gson();
            ChooseBabyDto chooseBabyDto = gson.fromJson(response, ChooseBabyDto.class);
            System.out.println(chooseBabyDto);
            return chooseBabyDto;
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        return null;
    }
    //更新宝宝状态
    public void updateBabyStatus( String status) {
        try {
            OkHttpClientUtils httpClient = new OkHttpClientUtils();
            String url = "http://admin.mi9688.top/api1/user/update-baby-choose-name-status/"+status;
            String response = httpClient.get(url);
            System.out.println(response);
        }catch (Exception e){
            Log.e("IndexActivity", "updateBabyStatus: "+e.getMessage());
    }
    }

    // 初始化WebSocket连接
    private void initWebSocket() {

        OkHttpClient client = new OkHttpClient();  // 创建OkHttpClient实例
        Request request = new Request.Builder().url("ws://192.168.129.148:9001").build();  // 创建WebSocket连接的请求
        WebSocketListener webSocketListener = new WebSocketListener() {  // 创建WebSocketListener实例
            @Override
            public void onOpen(@NonNull WebSocket webSocket, @NonNull Response response) {
                super.onOpen(webSocket, response);
                // 连接成功回调
                System.out.println("连接成功！！！");
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        TextView lineView = findViewById(R.id.line);//婴儿信息
                        lineView.setText("连接状态：连接成功");


                    }
                });

                //获取当前选中宝宝

                ChooseBabyDto baby = getCurrentBaby();
                if(baby != null) {
                    currentBaby=baby.getName();

                }

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        TextView babyView = findViewById(R.id.baby);//婴儿信息
                        if(babyView != null) {
                            //更新婴儿信息
                            babyView.setText("当前婴儿: " + currentBaby);
                        } else {
                            Log.e("IndexActivity", "TextView babyView is null");
                        }

                    }
                });
            }


            private boolean isEyesClosed = false; // 用于标记是否闭眼状态
            private Handler handler = new Handler();
            private static final int CLOSED_EYES_DELAY = 5000; // 闭眼持续时间，单位毫秒

            @Override
            public void onMessage(WebSocket webSocket, String text) {
                super.onMessage(webSocket, text);
                Log.d("接收消息", text);

                Gson gson = new Gson();
                Message message = gson.fromJson(text, Message.class);
                Log.d("反序列化", message.toString());

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        TextView statusTextView = findViewById(R.id.status); // 状态
                        TextView  sleepView = findViewById(R.id.sleep);//睡眠
                        TextView awakeview = findViewById(R.id.awake);//醒着
                        TextView kickview = findViewById(R.id.kick);//踢腿

                        //更新状态
                        if (message.getEye() == 1) {
                            if(statusTextView.getText().equals("睡觉中")){

                                awakeCount++;
                                awakeview.setText("醒着次数：" + awakeCount);


                            }

                            statusTextView.setText("婴儿状态：醒着"); // 设置文本内容为睁眼
                            status="醒着";
                            if(awakeCount==0){
                                awakeCount++;
                                awakeview.setText("醒着次数：" + awakeCount);

                            }

                            if (isEyesClosed) {
                                handler.removeCallbacksAndMessages(null); // 移除之前的闭眼延迟任务
                                isEyesClosed = false;
                            }{

                            }

                            statusTextView.setText("婴儿状态：醒着"); // 设置文本内容为睁眼
                            status="醒着";
                            if(awakeCount==0){
                                awakeCount++;
                                awakeview.setText("醒着次数：" + awakeCount);

                            }

                            if (isEyesClosed) {
                                handler.removeCallbacksAndMessages(null); // 移除之前的闭眼延迟任务
                                isEyesClosed = false;
                            }
                        } else if(message.getEye() == 0){
                            if(!statusTextView.getText().equals("睡觉中")){
                                statusTextView.setText("婴儿状态：闭眼");
                                status="闭眼";


                            }

                            if (!isEyesClosed) {
                                isEyesClosed = true;
                                handler.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        statusTextView.setText("婴儿状态：睡觉中"); // 设置文本内容为睡觉中
                                        status="睡觉中";

                                        sleepCount++;
                                        sleepView.setText("睡觉次数：" + sleepCount);
                                    }
                                }, CLOSED_EYES_DELAY);
                            }
                        }
                        if(message.getKickLegLeft()==1||message.getKickLegRight()==1){
                            statusTextView.setText("婴儿状态：踢腿");
                            status="踢腿";

                            kickCount++;
                            kickview.setText("踢腿次数：" + kickCount);
                        }


                    }
                });
            }
        };
        webSocket = client.newWebSocket(request, webSocketListener);  // 建立WebSocket连接
    }

    // 处理权限请求的结果
    private static final int REQUEST_CAMERA_PERMISSION = 200;

    private final TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            openCamera();  // 当SurfaceTexture可用时打开相机
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
            // 处理SurfaceTexture大小变化
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
            // SurfaceTexture更新时的回调
        }
    };

    private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(@NonNull CameraDevice camera) {
            cameraDevice = camera;  // 相机打开后的回调，保存相机设备实例
            createCameraPreviewSession();  // 创建相机预览会话
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice camera) {
            cameraDevice.close();  // 相机断开连接后的回调，关闭相机
        }

        @Override
        public void onError(@NonNull CameraDevice camera, int error) {
            cameraDevice.close();  // 相机发生错误后的回调，关闭相机
            cameraDevice = null;
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);



        initWebSocket();  // 初始化WebSocket连接
//        webSocket.send("连接辣");  // 发送消息到服务器
        setContentView(R.layout.activity_index);  // 设置布局文件

        textureView = findViewById(R.id.camera_view);  // 初始化TextureView

        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        int screenWidth = displayMetrics.widthPixels;
        int halfScreenHeight = displayMetrics.heightPixels;

        textureView.setLayoutParams(new ViewGroup.LayoutParams(screenWidth, halfScreenHeight));

        textureView.setSurfaceTextureListener(textureListener);  // 设置SurfaceTexture监听器
    }
    private Executor executor = Executors.newSingleThreadExecutor();
    private volatile long lastProcessedTime = 0; // 上一次处理图像的时间

    //图像编码格式转换，把fuv转成nv21格式
    public  byte[] convertYUV420888ToNV21(Image image) {
        ByteBuffer yBuffer = image.getPlanes()[0].getBuffer();
        ByteBuffer uBuffer = image.getPlanes()[1].getBuffer();
        ByteBuffer vBuffer = image.getPlanes()[2].getBuffer();

        int ySize = yBuffer.remaining();
        int uSize = uBuffer.remaining();
        int vSize = vBuffer.remaining();

        byte[] nv21 = new byte[ySize + uSize + vSize];

        // 复制Y分量数据
        yBuffer.get(nv21, 0, ySize);

        // 每个U、V分量的步长（因为它们是交错存储的）
        int uvPixelStride = image.getPlanes()[1].getPixelStride(); // 通常是2
        int uvRowStride = image.getPlanes()[1].getRowStride(); // U分量和V分量行的跨度可能不同

        // U、V分量数据交错复制
        for (int row = 0; row < image.getHeight() / 2; row++) {
            int yPos = ySize + row * uvRowStride;
            int uvPos = yPos;

            for (int col = 0; col < uvRowStride; col += uvPixelStride) {
                nv21[uvPos++] = uBuffer.get(row * uvRowStride + col);
                nv21[uvPos++] = vBuffer.get(row * uvRowStride + col);
            }
        }

        return nv21;
    }




    // 打开相机
    private void openCamera() {
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);  // 获取相机管理器
        try {
            String cameraId = manager.getCameraIdList()[0];  // 获取相机ID
            CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);  // 获取相机特性
            StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);  // 获取流配置映射
            assert map != null;
            imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];  // 获取图像尺寸

            // 初始化ImageReader
            imageReader = ImageReader.newInstance(2048, 1536, ImageFormat.YUV_420_888, 3);  // 创建ImageReader实例
            imageReader.setOnImageAvailableListener(reader -> {
                long currentTime = System.currentTimeMillis();
                if (currentTime - lastProcessedTime >= 1000) { // 1000毫秒处理一次
                    executor.execute(() -> {
                        updateBabyStatus(status);
                        try (Image image = reader.acquireLatestImage()) {//获取最新图像
                            if (image != null) {

//                              //图像转换编码并压缩为jpeg格式
                                byte[] bytes = convertYUV420888ToNV21(image);

                                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                YuvImage yuvImage = new YuvImage(bytes, ImageFormat.NV21, image.getWidth(), image.getHeight(), null);
                                yuvImage.compressToJpeg(new Rect(0, 0, image.getWidth(), image.getHeight()), 80, outputStream);
                                byte[] jpegData = outputStream.toByteArray();

                                // 发送 JPEG 数据到 WebSocket
                                webSocket.send(ByteString.of(jpegData));

                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            lastProcessedTime = System.currentTimeMillis(); // 更新上一次处理图像的时间
                        }
                    });
                } else {
                    // 如果不处理这一帧图像，也要确保释放它，避免内存泄露
                    Image image = reader.acquireLatestImage();
                    if (image != null) {
                        image.close();
                    }
                }
            }, new Handler(Looper.getMainLooper()));

            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);  // 请求相机权限
                return;
            }
            manager.openCamera(cameraId, stateCallback, null);  // 打开相机
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }


    private void createCameraPreviewSession() {
        try {
            SurfaceTexture texture = textureView.getSurfaceTexture();
            assert texture != null;
            texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
            Surface surface = new Surface(texture);

            // 获取屏幕的宽高比和相机预览的宽高比
            int viewWidth = textureView.getWidth();
            int viewHeight = textureView.getHeight();
            float screenAspectRatio = (float) viewWidth / viewHeight;
            float previewAspectRatio = (float) imageDimension.getWidth() / imageDimension.getHeight();

            // 计算缩放比例，此处加大缩放比以确保填满屏幕
            float scaleX = 1.0f, scaleY = 1.0f;
            if (screenAspectRatio > previewAspectRatio) {
                // 增加缩放比例以确保宽度填满屏幕
                scaleY = (screenAspectRatio / previewAspectRatio) * 0.9f; // 比原来多10%的缩放
            } else {
                // 增加缩放比例以确保高度填满屏幕
                scaleX = (previewAspectRatio / screenAspectRatio) * 0.55f; // 比原来多10%的缩放
            }

            // 应用缩放以填充并稍微裁剪TextureView
            textureView.setScaleX(scaleX);
            textureView.setScaleY(scaleY);

            captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            captureRequestBuilder.addTarget(surface);

            captureRequestBuilder.addTarget(imageReader.getSurface());

            cameraDevice.createCaptureSession(Arrays.asList(surface, imageReader.getSurface()), new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession session) {
                    if (null == cameraDevice) {
                        return;
                    }
                    cameraCaptureSession = session;
                    updatePreview();
                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                    Toast.makeText(IndexActivity.this, "Configuration change", Toast.LENGTH_SHORT).show();
                }
            }, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }




    // 更新预览
    private void updatePreview() {
        if(null == cameraDevice) {
            return;
        }
        captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);  // 设置捕获请求的控制模式为自动
        try {
            cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null);  // 设置重复捕获请求
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CAMERA_PERMISSION) {
            if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
                // 告诉用户为什么需要这个权限，并尝试再次请求权限。
                Toast.makeText(IndexActivity.this, "You can't use camera without permission.", Toast.LENGTH_LONG).show();  // 显示提示信息
                // 结束应用或者采取其他适当措施
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (cameraDevice != null) {
            cameraDevice.close();  // 暂停时关闭相机
            cameraDevice = null;
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        try {
            OkHttpClientUtils httpClient = new OkHttpClientUtils();
            String url = "http://admin.mi9688.top/api1/records/save/"+currentBabyId+"/"+sleepCount+"/"+
                    awakeCount+"/"+kickCount;
            String response = httpClient.get(url);
        }        catch (Exception e) {

        }


    }
}

